<!DOCTYPE html>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title> 3n + 1 Game </title>
	<link rel="stylesheet" href="./machine_plus.css">
	<style>
		th {
			height: 26px;
			text-align: right;
			font-family: 'arial black';
		}

		thead th {
			min-width: 10em;
			text-align: center;
			background-color: #FE3;
		}
	</style>
</head>

<body>
	<a href="http://www.matrix67.com/blog/archives/6756">根据 Matrix67 博客中的题目所做的练习。</a>
	<p>任意取一个正整数 n 。如果 n 是奇数，则把 n 变为 3 · n + 1 ；如果 n 是偶数，则把 n 变为 n/2 。不断重复操作，则最终一定会得到 1 。</p>
	Input Number: <input type="number" id="ipt" />

	<div id="insertCount"></div>

	<table>
		<thead>
			<tr>
				<th>Decimal</th>
				<th>Ternary</th>
			</tr>
		</thead>
		<tbody id="insertRow"> </tbody>
	</table>

	<script type="text/javascript" src="./ternary.js"></script>
	<script>
		'use strict';

		const insertRow = document.querySelector('#insertRow');
		const insertCount = document.querySelector('#insertCount');
		let track = [];

		// one trip
		function trip(num) {
			let robot = 0, carry = 1, jmp = 0;
			for (let i = track.length - 1; i >= 0; i--) {
				if (track[i]) break;
				track.pop();
			}
			// single move
			for (let i = track.length - 1; i >= 0; i--) {
				jmp = track[i];
				track[i] = track[i] ^ robot ^ carry;
				carry = (jmp + robot + carry) >> 1;
				robot = jmp;

				// if (!track[i] && i == track.length - 1) track.pop();

				if (!i) {
					if (robot | carry) {
						if (robot & carry) track.unshift(0);
						track.unshift(1);
					}
				}
			}
		}

		function addRow() {
			let tr = document.createElement("tr");
			let td1 = document.createElement("th");
			let td2 = document.createElement("th");

			tr.appendChild(td1);
			tr.appendChild(td2);
			insertRow.appendChild(tr);

			return { td1, td2 };
		}

		// Show Step In Web
		function showSteps(num) {

			insertRow.textContent = '';

			// checkSteps(num);
			// initial track;
			track = Array.from(num.toString(2)).map(e => +e);

			let cnt = 0;

			while (num > 4) {
				let tr = addRow();
				tr.td1.textContent = num;
				tr.td2.textContent = track.join('');
				trip(num);
				num = Number.parseInt(track.join(''), 2);
			}

			insertCount.textContent = cnt + ' rows, ' + track.length + ' width';
		}

		// add Event Listener
		(() => {
			document.getElementById('ipt').addEventListener('change', function (evn) {
				showSteps(Math.abs(parseInt(this.value, 10)));
			}, false);
		})();
	</script>

</body>

</html>